using System;
using FireStarterModeller.BO;
using Habanero.Testability;

namespace FireStarterModeller.Test
{
    public class TestUtilsDMProperty
    {
        protected readonly static BOTestFactory<DMProperty> _factory = GetTestFactory();

        public static BOTestFactory<DMProperty> GetTestFactory()
        {
            return BOTestFactoryRegistry.Instance.Resolve<DMProperty>();
        }

        /// <summary>
        /// Creates a new saved DMProperty with a random value assigned to every property
        /// </summary>
        public static DMProperty CreateSavedDMProperty()
        {
            DMProperty dMProperty = CreateUnsavedValidDMProperty();
            dMProperty.Save();
            return dMProperty;
        }

        /// <summary>
        /// Creates a new unsaved DMProperty with a random value assigned to every property
        /// </summary>
        public static DMProperty CreateUnsavedValidDMProperty()
        {
            DMProperty dMProperty = CreateUnsavedValidDMProperty_WithClassNull();
            dMProperty.Class = TestUtilsDMClass.CreateUnsavedValidDMClass();
            dMProperty.PropertyTypeString = DMPropertyType.PROP_TYPE_STRING;
            return dMProperty;
        }

        /// <summary>
        /// Creates a new unsaved DMProperty with a random value assigned to every property
        /// </summary>
        public static DMProperty CreateUnsavedValidDMProperty(IDMClass dmClass)
        {
            DMProperty dMProperty = CreateUnsavedValidDMProperty_WithClassNull(false);
            dMProperty.Class = dmClass;
            if (dmClass != null)
            {
                var solution = dmClass.Solution;
                if (solution != null) dMProperty.PropertyType = solution.GetDMPropertyType("System.String");
            }
            return dMProperty;
        }

        /// <summary>
        /// Creates a new unsaved DMProperty where all properties are null, except ID properties
        /// and those with default values.  If there are compulsory properties without
        /// defaults, saving the object will throw an exception.
        /// </summary>
        public static DMProperty CreateUnsavedDefaultDMProperty()
        {
            DMProperty dMProperty = new DMProperty();
            return dMProperty;
        }

        /// <summary>
        /// Creates a new unsaved DMProperty where all properties are null, except ID properties
        /// and those with default values and the DMClass which is set.  If there are compulsory properties without
        /// defaults, saving the object will throw an exception.
        /// </summary>
        public static DMProperty CreateUnsavedDefaultDMPropertyWithClass()
        {
            DMProperty dMProperty = new DMProperty();
            dMProperty.Class = TestUtilsDMClass.CreateUnsavedValidDMClass();
            return dMProperty;
        }

        /// <summary>
        /// Creates a new unsaved DMProperty where all properties are null, except ID properties
        /// and those with default values and the DMClass which is set.  If there are compulsory properties without
        /// defaults, saving the object will throw an exception.
        /// </summary>
        public static DMProperty CreateUnsavedDefaultDMPropertyWithClass(DMSolution solution)
        {
            DMProperty dMProperty = new DMProperty();
            dMProperty.Class = TestUtilsDMClass.CreateUnsavedDefaultDMClass(solution);
            return dMProperty;
        }

        public static DMProperty CreateUnsavedValidDMProperty(IDMClass dmClass, bool keepValuePrivate)
        {
            DMProperty dMProperty = CreateUnsavedValidDMProperty_WithClassNull();
            dMProperty.Class = dmClass;
            dMProperty.KeepValuePrivate = keepValuePrivate;
            return dMProperty;
        }

        public static DMProperty CreateUnsavedValidDMProperty_WithClassNull()
        {
            return CreateUnsavedValidDMProperty_WithClassNull(true);
        }

        public static DMProperty CreateUnsavedValidDMProperty_WithClassNull(bool setPropType)
        {
            DMProperty dMProperty = new DMProperty();
            SetDMPropTOValidValues(dMProperty, setPropType);

            return dMProperty;
        }

        public static DMProperty SetDMPropTOValidValues(DMProperty dMProperty)
        {
            SetDMPropTOValidValues(dMProperty, true);
            return dMProperty;
        }

        public static DMProperty SetDMPropTOValidValues(DMProperty dMProperty, bool setPropType)
        {
            dMProperty.PropertyName = TestUtilsShared.GetRandomString();
            //dMProperty.ReadWriteRule = null;
            dMProperty.MappedDBColumnName = TestUtilsShared.GetRandomString();
            dMProperty.Description = TestUtilsShared.GetRandomString();
            dMProperty.Compulsory = TestUtilsShared.GetRandomBoolean();
            //dMProperty.AutoIncrementing = TestUtilsShared.GetRandomBoolean();
            dMProperty.AutoIncrementing = false;
            dMProperty.Length = TestUtilsShared.GetRandomInt();
            dMProperty.KeepValuePrivate = TestUtilsShared.GetRandomBoolean();
            dMProperty.DisplayName = TestUtilsShared.GetRandomString();
            dMProperty.DefaultValue = TestUtilsShared.GetRandomString();
            dMProperty.Generated = false;
            dMProperty.LookupListID = TestUtilsDMLookupList.CreateSavedDMLookupList().LookupListID;
            if (setPropType)
            {
                dMProperty.PropertyTypeID = TestUtilsDMPropertyType.CreateSavedDMPropertyType().PropertyTypeID;
            }

            dMProperty.MappedDBColumnID = Guid.NewGuid();
            if (dMProperty.OrdinalPosition == null) dMProperty.OrdinalPosition = TestUtilsShared.GetRandomInt();
            return dMProperty;
        }

        public static DMProperty SetDMPropStringType(DMProperty dMProperty)
        {
            return SetDMPropType(dMProperty, TestUtilsDMPropertyType.CreateSavedStringPropertyType());
        }

        public static DMProperty SetDMPropIntType(DMProperty dMProperty)
        {
            return SetDMPropType(dMProperty, TestUtilsDMPropertyType.CreateSavedIntPropertyType());
        }
        public static DMProperty SetDMPropCustomType(DMProperty dMProperty)
        {
            return SetDMPropType(dMProperty, TestUtilsDMPropertyType.CreateUnsavedValidDMPropertyType());
        }

        private static DMProperty SetDMPropType(DMProperty property, DMPropertyType propType)
        {
            property.PropertyName = TestUtilsShared.GetRandomString();
            //property.ReadWriteRule = null;
            property.MappedDBColumnName = TestUtilsShared.GetRandomString();
            property.Description = TestUtilsShared.GetRandomString();
            property.Compulsory = TestUtilsShared.GetRandomBoolean();
            property.Length = TestUtilsShared.GetRandomInt();
            property.KeepValuePrivate = false;
            property.DisplayName = TestUtilsShared.GetRandomString();
            property.DefaultValue = TestUtilsShared.GetRandomString();
            property.Generated = false;
            property.PropertyType = propType;
            if (property.OrdinalPosition == null) property.OrdinalPosition = TestUtilsShared.GetRandomInt();
            return property;
        }

        public static DMProperty SetDMPropBooleanType(DMProperty property)
        {
            return SetDMPropType(property, TestUtilsDMPropertyType.CreateSavedBooleanPropertyType());
        }

        public static DMProperty SetDMPropWithLookupList(DMProperty property)
        {
            DMProperty dmProperty = SetDMPropType(property, TestUtilsDMPropertyType.CreateUnsavedStringPropertyType());
            dmProperty.LookupList = TestUtilsDMLookupList.CreateSavedDMLookupList();
            return dmProperty;
        }

        public static DMProperty SetDMPropWithDateTime(DMProperty property)
        {
            return SetDMPropType(property, TestUtilsDMPropertyType.CreateSavedDateTimePropertyType());
        }

        public static void CreateUnsavedValidDMProperties(DMClass dmClass, int numberOfProps)
        {
            for (int i = 0; i < numberOfProps; i++)
            {
                CreateUnsavedValidDMProperty(dmClass);
            }
        }

        public static DMProperty CreateDMProperty(DMClass dmClass, string propertyName, string typeAssembly, string typeName)
        {
            DMProperty dmProperty = dmClass.Properties.CreateBusinessObject();
            dmProperty.PropertyName = propertyName;
            dmProperty.HasSetter = true;
            dmProperty.PropertyType = DMPropertyType.FindOrCreate((DMSolution) dmClass.Solution, typeAssembly, typeName);
            return dmProperty;
        }

    }
}